home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_052 / tek4010 / remote.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  12KB  |  512 lines

  1. /*
  2. .index remote.c
  3.  */
  4. /****************************************************
  5.  * vt100 emulator - remote character interpretation
  6.  *
  7.  *           Oct 86 TAW - added tek 4010 emulation and did some
  8.  *                      - minor bug fixes, I use Move/Draw instead of
  9.  *                      - RectFill, added the box to the extened character 
  10.  *              set
  11.  *           860823 DBW - Integrated and rewrote lots of code
  12.  *      v2.0 860803 DRB - Rewrote the control sequence parser
  13.  *      v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
  14.  *      v1.0 860712 DBW - First version released
  15.  *
  16.  ****************************************************/
  17.  
  18. #include "vt100.h"
  19.  
  20. static int    p [10];
  21. static int    numpar;
  22. static char   escseq[40];
  23.  
  24. void doctrl ();
  25. void doesc ();                           /* force correct denomination */
  26. void doerase ();
  27. void doindex ();
  28. /*
  29. .page.index doremote
  30.  */
  31. /************************************************
  32. *  function to handle remote characters
  33. *************************************************/
  34. void 
  35. doremote (c)
  36. char c;
  37.     {
  38.     if (Tek (c)) 
  39.     return;
  40.     if (inesc >= 0) 
  41.     { 
  42.     doesc (c); 
  43.     return; 
  44.     }
  45.     if (inctrl >= 0) 
  46.     { 
  47.     doctrl (c); 
  48.     return; 
  49.     }
  50.  
  51.     switch (c) 
  52.     {
  53.     case 15:
  54.         alt = 0;
  55.     break;
  56.     case 14:
  57.         alt = 1;
  58.         break;
  59.     case '\t':
  60.     x += 64 - ((x-MINX) % 64);
  61.         break;
  62.     case 10:  /* lf */
  63.     case 11:
  64.     case 12:
  65.         if (nlmode) 
  66.         doindex ('E');
  67.     else 
  68.         doindex ('D');
  69.         break;
  70.     case 13:  /* cr */
  71.         if (!nlmode) 
  72.         x = MINX;
  73.         break;
  74.     case 8:   /* backspace */
  75.         x -= 8;
  76.         if (x < MINX) 
  77.         x = MINX;
  78.         break;
  79.  
  80.     case 7:     /* bell */
  81.         DisplayBeep (NULL);
  82.         break;
  83.     case 27:
  84.         inesc = 0;
  85.         break;
  86.     default:
  87.         if (c < ' ' || c > '~') 
  88.         return;
  89.         if (a[alt] && c > '`')
  90.         doalt (c);
  91.         else
  92.         emitbatch (1,&c);
  93.         } /* end of switch */
  94.     }/* end doremote */
  95. /*
  96. .page.index doesc
  97.  */
  98. void 
  99. doesc (c)
  100. char c;
  101. {
  102.     if (inesc < 0) 
  103.     { 
  104.     inesc = 0; 
  105.     return; 
  106.     }
  107.     if (c == 27 || c == 24) 
  108.     { inesc = -1; 
  109.     return; 
  110.     }
  111.  
  112.     if (c < ' ' || c == 127)    /* Ignore control chars */
  113.     return;              
  114.  
  115.     if (c < '0')         /* Collect intermediates */
  116.     {
  117.     escseq [inesc++] = c; 
  118.     return; 
  119.     }  
  120.  
  121.     /* by process of elimination, we have a final character.  Put it in
  122.        the buffer, and dispatch on the first character in the buffer */
  123.  
  124.     escseq [inesc] = c;
  125.     inesc = -1;                         /* No longer collecting a sequence */
  126.     switch (escseq[0])                  /* Dispatch on the first received */
  127.         {
  128.     case '[':                           /* Control sequence introducer */
  129.         numpar = 0;                     /* No parameters yet */
  130.         private = 0;                    /* Not a private sequence (yet?) */
  131.         badseq = 0;                     /* Good until proven bad */
  132.         p[0] = p[1] = 0;                /* But default the first parameter */
  133.         inctrl = 0;                     /* We are in a control sequence */
  134.         return;                         /* All done for now ... */
  135.     case 'D': case 'E': case 'M':       /* Some kind of index */
  136.         doindex (c);                    /* Do the index */
  137.         return;                         /* Return */
  138.     case '7':                           /* Save cursor position */
  139.         savx = x; savy = y; savmode = curmode; savalt = alt;
  140.         sa[0] = a[0]; sa[1] = a[1];
  141.         return;
  142.     case '8':                         /* Restore cursor position */
  143.         x = savx; y = savy; alt = savalt; curmode = savmode;
  144.         a[0] = sa[0]; a[1] = sa[1];
  145.         return;
  146.     case 'c':                         /* Reset */
  147.         top = MINY; bot = MAXY; savx = MINX; savy = MINY;
  148.         a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
  149.         emit(12); 
  150.     inesc = -1;
  151.         return;
  152.     case '(':                         /* Change character set */
  153.         if (c == '0' || c == '2') 
  154.         a[0] = 1; 
  155.     else 
  156.         a[0] = 0;
  157.         return;
  158.     case ')':                         /* Change the other character set */
  159.         if (c == '0' || c == '2') 
  160.         a[1] = 1; 
  161.     else 
  162.         a[1] = 0;
  163.         return;
  164.     /* If we didn't match anything, we can just return, happy in the
  165.      * knowledge that we've at least eaten the whole sequence */
  166.         }/* end switch */
  167.     return;
  168. }/* end doesc */
  169.  
  170. /*
  171. .page.index doctrl
  172.  */
  173. void 
  174. doctrl (c)
  175. char c;
  176. {
  177.     int     i;
  178.  
  179.     if (c == 27 || c == 24) 
  180.     { 
  181.     inctrl = -1; 
  182.     return; 
  183.     }
  184.     if (c < ' ' || c == 127)         /* Ignore control chars */
  185.     return;              
  186.  
  187.     /* First, look for some parameter characters.  If the very first
  188.      * parameter character isn't a digit, then we have a private sequence */
  189.  
  190.     if (c >= '0' && c < '@')
  191.     {
  192.         /* can't have parameters after intermediates */
  193.         if (inctrl > 0) 
  194.         {
  195.         badseq++; 
  196.             return; 
  197.         }
  198.         switch (c)
  199.             {
  200.         case '0': case '1': case '2': case '3': case '4':
  201.         case '5': case '6': case '7': case '8': case '9':
  202.             p[numpar] = p[numpar] * 10 + (c - '0');
  203.             return;
  204.  
  205.         case ';':
  206.             p[++numpar] = 0;            /* Start a new parameter */
  207.             return;
  208.  
  209.         case '<': case '=': case '>': case '?': /* Can only mean private */
  210.             if (inctrl = 0) private = c; /* Only allowed BEFORE parameters */
  211.             return;
  212.  
  213.         /* if we come here, it's a bad sequence */
  214.             }
  215.         badseq++;                       /* Flag the bad sequence */
  216.         }
  217.  
  218.     if (c < '0')                        /* Intermediate character */
  219.     {
  220.         escseq[inctrl++] = c;           /* Save the intermediate character */
  221.         return;
  222.     }
  223.  
  224.     /* if we get here, we have the final character.  Put it in the 
  225.        escape sequence buffer, then dispatch the control sequence */
  226.     numpar++;                           /* Reflect the real number of parameters */
  227.     escseq[inctrl++] = c;               /* Store the final character */
  228.     escseq[inctrl] = '\000';            /* Tie off the buffer */
  229.     inctrl = -1;                        /* End of the control sequence scan */
  230.  
  231.     /* Don't know how to do any private sequences right now, 
  232.      * so just punt them */
  233.     if (private != 0 || badseq != 0) 
  234.     return;
  235.  
  236.     switch (escseq[0])                  /* Dispatch on first intermediate or final */
  237.         {
  238.     case 'A': 
  239.     if (p[0]<=0) 
  240.         p[0] = 1;
  241.     y -= 8*p[0]; 
  242.     if (y<top)  
  243.         y = top;  
  244.     return;
  245.     case 'B': 
  246.     if (p[0]<=0) 
  247.         p[0] = 1;                
  248.     y += 8*p[0]; 
  249.     if (y>bot)  
  250.         y = bot;  
  251.     return;
  252.     case 'C': 
  253.     if (p[0]<=0) 
  254.         p[0] = 1;        
  255.     x += 8*p[0]; 
  256.     if (x>MAXX) 
  257.         x = MAXX; 
  258.     return;
  259.     case 'D': 
  260.     if (p[0]<=0) 
  261.         p[0] = 1;  
  262.     x -= 8*p[0]; 
  263.     if (x<MINX) 
  264.         x = MINX; 
  265.     return;
  266.     case 'H': case 'f':               /* Cursor position */
  267.         if (p[0] <= 0) 
  268.         p[0] = 1;
  269.         if (p[1] <= 0) 
  270.         p[1] = 1;
  271.         y = (--p[0]*8)+MINY; 
  272.     x = (--p[1]*8)+MINX;
  273.         if (y > MAXY) 
  274.         y = MAXY;
  275.         if (x > MAXX) 
  276.         x = MAXX;
  277.         if (y < MINY) 
  278.         y = MINY;
  279.         if (x < MINX) 
  280.         x = MINX;
  281.         return;
  282.     case 'r':                         /* Set scroll region */
  283.         if (p[0] <= 0) 
  284.         p[0] = 1;
  285.         if (p[1] <= 0) 
  286.         p[1] = p_lines;
  287.         top = (--p[0]*8)+MINY; 
  288.     bot = (--p[1]*8)+MINY;
  289.         if (top < MINY) 
  290.         top = MINY;
  291.         if (bot > MAXY) 
  292.             bot = MAXY;
  293.         if (top > bot) 
  294.         { 
  295.         top = MINY; 
  296.         bot = MAXY; 
  297.         }
  298.         x = MINX; 
  299.     y = MINY;
  300.         return;
  301.     case 'm':                         /* Set graphic rendition */
  302.         for (i=0; i<numpar; i++) 
  303.         {
  304.             if (p[i] < 0) 
  305.         p[i] = 0;
  306.             switch (p[i]) 
  307.         {
  308.             case 0:
  309.                 curmode  = 0;
  310.                 break;
  311.  
  312.             case 1:
  313.             case 5:
  314.                 if (p_depth > 1)    
  315.             curmode |= BOLD;
  316.                 else
  317.                     curmode |= REVERSE;
  318.                 break;
  319.  
  320.             case 4:
  321.                 curmode |= UNDERLINE;
  322.                 break;
  323.  
  324.             default:
  325.                 curmode |= REVERSE;
  326.                 break;
  327.                 }
  328.             }
  329.         return;
  330.  
  331.     case 'K':                         /* Erase in line */
  332.         doerase ();
  333.         return;
  334.  
  335.     case 'J':                         /* Erase in display */
  336.         if (p[0] < 0) 
  337.         p[0] = 0;
  338.         SetAPen (mywindow->RPort,0L);
  339.         if (p[0] == 0) 
  340.         {
  341.             if (y < MAXY) 
  342.         RectFill (mywindow->RPort,
  343.                        (long)MINX,(long)(y+2),(long)(MAXX+7),(long)(MAXY+1));
  344.             }
  345.         else if (p[0] == 1) 
  346.         {
  347.             if (y > MINY) 
  348.         RectFill (mywindow->RPort,
  349.                        (long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(y-7));
  350.             }
  351.         else 
  352.         RectFill (mywindow->RPort,
  353.                     (long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
  354.         SetAPen (mywindow->RPort,1L);
  355.         doerase (); 
  356.     return;
  357.  
  358.     case 'h':                         /* Set parameter */
  359.         if (p[0] == 20) 
  360.         nlmode = 1;
  361.         return;
  362.  
  363.     case 'l':                         /* Reset parameter */
  364.         if (p[0] == 20) 
  365.         nlmode = 0;
  366.         return;
  367.  
  368.     case 'x':
  369.         sendchar (27); 
  370.     sendstring ("[3;1;8;64;64;1;0x"); 
  371.     return;
  372.  
  373.     case 'n':
  374.         if (p[0] == 6) {
  375.             sendchar (27);
  376.             sprintf (escseq,"[%d;%dR",((y-MINY)/8)+1,((x-MINX)/8)+1);
  377.             sendstring (escseq); 
  378.         return;
  379.             }
  380.         sendchar (27); 
  381.     sendstring ("[0n"); 
  382.     return;
  383.  
  384.     case 'c':
  385.         sendchar (27); 
  386.     sendstring ("[?1;0c"); 
  387.     return;
  388.     }
  389.  
  390.     /* Don't know how to do this one, so punt it */
  391. }/* end doctrl */
  392. /*
  393. .page.index doindex
  394.  */
  395. void 
  396. doindex (c)
  397. char c;
  398.     {
  399.     if (c != 'M') 
  400.     {
  401.         if (c == 'E') 
  402.          x = MINX;
  403.         if (y > bot) 
  404.         if (y < MAXY) 
  405.         y += 8;
  406.         if (y == bot)
  407.             ScrollRaster (mywindow->RPort,0L,8L,(long)MINX,(long)(top-6),
  408.                                                (long)(MAXX+7),(long)(bot+1));
  409.         if (y < bot) 
  410.         y += 8;
  411.         }
  412.     else 
  413.     {
  414.         if (y < top) 
  415.         if (y > MINY) 
  416.         y -= 8;
  417.         if (y == top)
  418.             ScrollRaster (mywindow->RPort,0L,-8L,(long)MINX,(long)(top-6),
  419.                                                (long)(MAXX+7),(long)(bot+1));
  420.         if (y > top) 
  421.         y -= 8;
  422.         }
  423.     return;
  424.     }/* end doindex */
  425. /*
  426. .page.index doalt
  427.  */
  428. doalt (c)
  429. char c;
  430.     {
  431.     int oldx, newx;
  432.     inesc = -1;
  433.     oldx = x; emit (' '); 
  434.     newx = x;
  435.     x = oldx;
  436.     SetAPen (mywindow->RPort,1L);
  437.     switch (c) 
  438.     {
  439.     case 'a':
  440.     c = 127;
  441.     emitbatch (1, &c);
  442.     break;
  443.     case 'j':
  444.     case 'm':
  445.     case 'v':   
  446.     doline (4,-8,4,-4);
  447.         if  (c=='j')  
  448.         doline (0,-4,4,-4);
  449.         else if (c=='m')  
  450.         doline (4,-4,8,-4);
  451.         else
  452.             doline (0,-4,8,-4);
  453.         break;
  454.     case 'k':
  455.     case 'l':
  456.     case 'w': 
  457.     doline (4,-4,4,0);
  458.         if (c=='k')
  459.         doline(0,-4,4,-4);
  460.         else if (c=='l')  
  461.         doline (4,-4,8,-4);
  462.         else              
  463.         doline (0,-4,8,-4);
  464.         break;
  465.     case 'n':
  466.     case 'q': 
  467.     doline (0,-4,8,-4);
  468.         if (c=='n')  
  469.         doline (4,-8,4,0);
  470.         break;
  471.     case 't':
  472.     case 'u':
  473.     case 'x':   
  474.     doline (4,-8,4,0);
  475.         if (c=='t')  
  476.         doline (4,-4,8,-4);
  477.         else if (c=='u')  
  478.         doline (0,-4,4,-4);
  479.         break;
  480.     }
  481.     x = newx;
  482.     }/* end doalt */
  483. /*
  484. .index doline
  485.  */
  486. doline (x1,y1,x2,y2) 
  487.     {
  488.     Move (mywindow->RPort, x+x1, y+y1);
  489.     Draw (mywindow->RPort, x+x2, y+y2);
  490.     }
  491. /*
  492. .index doerase
  493.  */
  494. void doerase ()
  495.     {
  496.     if (p[0] < 0) 
  497.     p[0] = 0;
  498.     SetAPen (mywindow->RPort,0L);
  499.     if (p[0] == 0) 
  500.     RectFill (mywindow->RPort,(long)x,(long)(y-6),
  501.                                                  (long)(MAXX+7),(long)(y+1));
  502.     else if (p[0] == 1)
  503.     RectFill (mywindow->RPort,
  504.                              (long)MINX,(long)(y-6),(long)(x+7),(long)(y+1));
  505.     else 
  506.     RectFill (mywindow->RPort,
  507.                           (long)MINX,(long)(y-6),(long)(MAXX+7),(long)(y+1));
  508.     SetAPen (mywindow->RPort,1L);
  509.     return;
  510.     }/* end doerase */
  511.  
  512.